package com.sunyu.springboot.controller;

import com.power.common.model.CommonResult;
import com.sunyu.springboot.enums.ErrorCodeEnum;
import com.sunyu.springboot.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

/**
 * @author yu 2019/2/17.
 */
@Slf4j
@RestController
@RequestMapping("defferredResult")
public class DeferredResultController {


    @Autowired
    private ThreadPoolTaskExecutor executor;

    @Autowired
    private AsyncService asyncService;
    /**
     *
     * @return
     */
    @GetMapping("/async-deferredresult")
    public DeferredResult<CommonResult<String>> handleReqDefResult(){
        log.info("Received async-deferredresult request");
        DeferredResult<CommonResult<String>> output = new DeferredResult<>();

        executor.submit(() -> {
            log.info("Processing in separate thread");
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                log.error("InterruptedException while executing the thread {}", e.fillInStackTrace());
            }
            output.setResult(CommonResult.ok());
        });

        log.info("servlet thread freed");
        return output;
    }


    @GetMapping("/timeout")
    public DeferredResult<CommonResult<String>> timeOut() {
        log.info("外部线程："+Thread.currentThread().getName());
        //设置超时60s
        DeferredResult<CommonResult<String>> result= new DeferredResult<>(5000L);
        result.onTimeout(()->{
            log.info("超时啦");
            result.setResult(CommonResult.fail(ErrorCodeEnum.TIME_OUT));
        });
        result.onCompletion(()->{
            log.info("完成咯");
        });
        executor.submit(()->{
            log.info("副线程处理业务");
            try {
                Thread.sleep(6000);
            }catch (InterruptedException e){
                log.error("超时中盾");
            }
            result.setResult(CommonResult.ok().setResult("DeferredResult"));
        });
        return result;
    }

    @GetMapping("findUserList")
    public DeferredResult<CommonResult> findUser() throws Exception{
        log.info("执行任务");
        DeferredResult<CommonResult> deferredResult = new DeferredResult<>();
        ListenableFuture future1 = asyncService.findUser("");
        ListenableFuture future2 = asyncService.findUser("");
        ListenableFuture future3 = asyncService.findUser("");
        //等待三个线程执行完毕，如果不写下面代码接口将直接返回
        while(true) {
            if(future1.isDone() && future3.isDone()&&future2.isDone()) {
                log.info("Task1 result: {}", future1.get());
                log.info("Task2 result: {}", future1.get());
                break;
            }
            Thread.sleep(1);
        }

        deferredResult.setResult(CommonResult.ok());
        return deferredResult;
    }
}
